package dao

import (
	"golang.org/x/net/context"
	"gorm.io/gorm/clause"
	"mini-app/internal/dal"
)

type IOnlineEventFilter interface {
	fmtFilter(ctx context.Context, tx dal.IOnlineEventDo, q *dal.Query) dal.IOnlineEventDo
}

var _ IOnlineEventFilter = (*OnlineEventFilter)(nil)

type OnlineEventFilter struct {
	ID        string
	Deleted   *int
	All       int
	ForUpdate bool
	Sort      *int
}

// 筛选器
func (p *OnlineEventFilter) fmtFilter(ctx context.Context, tx dal.IOnlineEventDo, q *dal.Query) dal.IOnlineEventDo {
	if p.ID != "" && p.ID != "0" {
		tx = tx.Where(q.OnlineEvent.ID.Eq(p.ID))
	}

	if p.ForUpdate {
		tx = tx.Clauses(clause.Locking{Strength: "UPDATE"})
	}

	if p.Sort != nil {
		if *p.Sort == 0 {
			// 查询 sort 为 0 或为 null 的记录
			tx = tx.Where(q.OnlineEvent.Sort.Eq(0)).Or(q.OnlineEvent.Sort.IsNull())
		} else {
			tx = tx.Where(q.OnlineEvent.Sort.Eq(*p.Sort))
		}
	}

	if p.All != 0 {
		//查询所有包括已经删除的
		tx = tx.Unscoped()
	} else if p.Deleted != nil {
		tx = tx.Where(q.OnlineEvent.DeletedAt.Eq(uint(*p.Deleted)))
	} else {
		//默认只查询未被删除的
		tx = tx.Where(q.OnlineEvent.DeletedAt.Eq(0))
	}
	return tx
}

type OnlineEventListFilter struct {
	ID      string
	Deleted *int
	All     int
	Top     int

	StartSort int
	EndSort   int
}

func (p *OnlineEventListFilter) fmtFilter(ctx context.Context, tx dal.IOnlineEventDo, q *dal.Query) dal.IOnlineEventDo {
	if p.ID != "" && p.ID != "0" {
		tx = tx.Where(q.OnlineEvent.ID.Eq(p.ID))
	}

	if p.All != 0 {
		//查询所有包括已经删除的
		tx = tx.Unscoped()
	} else if p.Deleted != nil {
		tx = tx.Where(q.OnlineEvent.DeletedAt.Eq(uint(*p.Deleted)))
	} else {
		//默认只查询未被删除的
		tx = tx.Where(q.OnlineEvent.DeletedAt.Eq(0))
	}

	if p.Top != 0 {
		tx = tx.Where(q.OnlineEvent.Top.Gte(p.Top))
	}

	// 按置顶字段降序排列，排序字段降序排列，最后按创建时间降序排列
	tx = tx.Order(q.OnlineEvent.Top.Desc()).
		Order(q.OnlineEvent.Sort.Desc()).
		Order(q.OnlineEvent.CreatedAt.Desc())

	if p.StartSort != 0 && p.EndSort != 0 {
		var startSort = p.StartSort
		var endSort = p.EndSort
		if p.StartSort > p.EndSort {
			swap := func(a, b *int) {
				*a, *b = *b, *a
			}

			swap(&startSort, &endSort)
		}

		tx = tx.Where(q.OnlineEvent.Sort.Gte(startSort)).Where(q.OnlineEvent.Sort.Lte(endSort))
	}
	return tx
}
